package com.zmn.mcc.business.interfaces.staff;

import com.zmn.common.dictionary.GlobalDict;
import com.zmn.common.dto.LoginStaff;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.office.excel.ExportExcel;
import com.zmn.mcc.common.constant.DpermitConsts;
import com.zmn.mcc.common.dto.permit.PermitLitDO;
import com.zmn.mcc.common.dto.permit.SpermitDTO;
import com.zmn.mcc.common.dto.staff.EngineerBasicInfoDRO;
import com.zmn.mcc.common.dto.staff.LoginStaffDO;
import com.zmn.mcc.common.dto.staff.StaffIdAndDayLimitDRO;
import com.zmn.mcc.model.entity.staff.McStaff;
import com.zmn.mcc.model.entity.staff.McStaffQuery;
import com.zmn.mcc.model.entity.staff.dingtalk.StaffDingTalk;
import com.zmn.mcc.model.vo.McStaffExportExcelVO;

import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * @author heguanghua
 * @since 2020/04/14 22:04
 */
public interface StaffBService {

    /**
     * 带有角色与数据权限相关字段的员工对象
     * 优先从缓存中读取，如缓存中不存在则重新写入后返回
     *
     * @param staffId 员工ID
     * @return
     */
    LoginStaffDO getLoginStaffByStaffId(Integer staffId);


    /**
     * 带有角色与数据权限相关字段的员工对象
     *
     * @param staff 员工原始对象
     * @return
     */
    LoginStaffDO getLoginStaffByMcStaff(McStaff staff);

    /**
     * 取得员工指定系统的功能权限列表
     * 员工自定义功能权限优先，未自定义则使用所属部门默认
     *
     * @param loginStaff 员工登录验证通过后返回的对象
     * @param sysId      系统ID
     * @return 简化功能权限对象列表
     */
    SpermitDTO listPermitByLoginStaff(LoginStaffDO loginStaff, Integer sysId);

    /**
     * 取得员工指定系统的功能权限列表
     * 员工自定义功能权限优先，未自定义则使用所属部门默认
     *
     * @param staffId  员工ID
     * @param dataType 数据权限类型 {@link DpermitConsts#TYPE_ORGANIZE}
     * @param clear    返回前是否整理权限列表，可为null，为空或false则不整理
     * @return 简化功能权限对象列表
     */
    SpermitDTO listDpermitByStaffId(Integer staffId, Integer dataType, Boolean clear);

    /**
     * 取得员工指定类型的数据权限列表
     * 员工自定义数据权限优先，未自定义则使用所属部门默认
     *
     * @param loginStaff 员工登录验证通过后返回的对象
     * @param dataType   数据权限类型 {@link DpermitConsts#TYPE_ORGANIZE}
     * @param clear      返回前是否整理权限列表，可为null，为空或false则不整理
     * @return 简化的数据权限对象列表或数据权限ID列表
     */
    SpermitDTO listDpermitByLoginStaff(LoginStaffDO loginStaff, Integer dataType, Boolean clear);

    /**
     * 根据员工和系统ID查询拥有的权限列表
     *
     * @param staffId
     * @param sysId
     * @return
     */
    SpermitDTO<PermitLitDO> listPermitBySysId(Integer staffId, Integer sysId);


    /**
     * 查询员工角色ID列表；如员工未自定义功能权限，则继承部门默认角色
     *
     * @param staffId    员工ID(非<code>null</code>)
     * @param deptId     员工部门ID (非<code>null</code>)
     * @param permitSelf 废弃
     * @return 角色ID列表
     */
    List<Integer> listRoleByStaff(Integer staffId, Integer deptId, @Deprecated Integer permitSelf);

    /**
     * 检验员工是否拥有"超级管理员角色"
     *
     * @param staffId
     * @return
     */
    boolean isSuperAdmin(Integer staffId);

    /**
     * 检验员工是否拥有"权限管理员角色"
     *
     * @param staffId
     * @return
     */
    boolean isAssignAdmin(Integer staffId);

    /**
     * 检验员工是否拥有"系统全局角色"
     *
     * @param staffId
     * @return
     */
    boolean isGlobalAdmin(Integer staffId);


    /**
     * 新增员工
     *
     * @param staff
     * @return
     */
    ResponseDTO addStaff(McStaff staff, LoginStaff loginStaff, String ip);

    /**
     * 修改员工
     *
     * @param staff
     * @param loginStaff
     * @return
     */
    ResponseDTO modifyStaff(McStaff staff, LoginStaff loginStaff, String ip);


    /**
     * 设置临时密码
     *
     * @param staffId 员工ID
     * @param tempPwd 临时密码
     * @return
     */
    ResponseDTO setTempPwd(Integer staffId, String tempPwd, LoginStaff loginStaff, String ip, String tmpPwdLogin);

    /**
     * 重置默认密码
     *
     * @param staffIds
     * @param loginStaff
     * @return
     */
    String resetPwd(String staffIds, LoginStaff loginStaff, String ip);

    /**
     * 设置不限IP日期
     *
     * @param staffId
     * @param dateRange
     * @param loginStaff
     * @return
     */
    ResponseDTO setOpenDate(Integer staffId, String dateRange, LoginStaff loginStaff, String ip);

    /**
     * 描述: 设置不限IP日期(批量)
     *
     * @param staffIds   staffIds
     * @param dateRange  dateRange
     * @param loginStaff loginStaff
     * @param ip         ip
     * @return com.zmn.common.dto2.ResponseDTO<java.lang.String>
     * @author jiafei
     * @since 2022/9/5 15:53
     */
    ResponseDTO<String> batchSetOpenDate(List<Integer> staffIds, String dateRange, LoginStaff loginStaff, String ip);

    /**
     * 设置IP白名单
     *
     * @param staffId
     * @param whitelist
     * @param loginStaff
     * @return
     */
    ResponseDTO setWhitelist(Integer staffId, Integer whitelist, LoginStaff loginStaff, String ip);

    /**
     * 绑定工程师
     *
     * @param staffId   员工ID
     * @param masterIds 工程师ID集，依次为言而有信、啄木鸟、一步维修、川南环保
     * @return
     */
    ResponseDTO bindMaster(Integer staffId, List<Integer> masterIds, String updater, String ip);


    /**
     * 修改员工自定义功能权限标识
     * 自动判定自定义标识
     *
     * @param staffId 员工ID
     * @param updater
     * @return
     */
    ResponseDTO setPermitSelf(Integer staffId, String updater);

    /**
     * 修改员工自定义功能权限标识
     *
     * @param staffId    员工ID
     * @param permitSelf 自定义功能权限标识，{@link GlobalDict#YESNO_YES}
     * @param updater
     * @return
     */
    ResponseDTO setPermitSelf(Integer staffId, Integer permitSelf, String updater);

    /**
     * 修改员工自定义数据权限标识
     * 自动判定自定义标识
     *
     * @param staffId     员工ID
     * @param dpermitType 数据权限类型，{@link DpermitConsts#TYPE_ORGANIZE}
     * @param updater
     * @return
     */
    ResponseDTO setDpermitSelf(Integer staffId, Integer dpermitType, String updater);

    /**
     * 修改员工自定义数据权限标识
     *
     * @param staffId     员工ID
     * @param dpermitType 数据权限类型，{@link DpermitConsts#TYPE_ORGANIZE}
     * @param dpermitSelf 自定义数据权限标识，{@link GlobalDict#YESNO_YES}
     * @param updater
     * @return
     */
    ResponseDTO setDpermitSelf(Integer staffId, Integer dpermitType, Integer dpermitSelf, String updater);

    /**
     * 描述: 根据钉钉返回的信息同步员工信息
     *
     * @param staff         员工实体
     * @param staffDingTalk 钉钉实体
     * @since 2020/5/30
     **/
    void synchroStaffByStaffDingTalkAndStaff(McStaff staff, StaffDingTalk staffDingTalk);

    /**
     * 生成密码盐值
     *
     * @return
     */
    String generateSalt();

    /**
     * 上传导入员工绩效excel
     *
     * @param inputStream
     * @param operator
     * @return
     */
    ResponseDTO importExcel(InputStream inputStream, String operator) throws IOException;

    /**
     * 导出员工管理列表
     *
     * @param query
     * @return
     * @author linfeng
     * @since 16:38 2020/07/09
     */
    ExportExcel<McStaffExportExcelVO> exportExcel(McStaffQuery query);


    /**
     * 临时密码是否过期判断
     *
     * @param logId
     * @return
     */
    Boolean enableLogin(Integer logId);

    /**
     * 描述: 根据员工id集合查询员工查询前溯天数
     *
     * @param staffIdList 员工id集合
     * @return List<StaffIdAndDayLimitDRO>
     * @author xujie
     * @since 2021/05/28
     **/
    List<StaffIdAndDayLimitDRO> listStaffIdAndDayLimitByStaffIdList(List<Integer> staffIdList);


    /**
     * 根据员工mail 获取员工钉钉ID
     *
     * @param mail
     * @return
     */
    String getDTalkIdByMail(String mail);

    /**
     * 描述: 查询
     *
     * @param query query
     * @return java.util.List<com.zmn.mcc.model.entity.staff.McStaff>
     * @author jiafei
     * @since 2022/7/28 15:57
     */
    List<McStaff> listByQuery(McStaffQuery query);

    /**
     * <p>
     * 流程结束之后获取到流程实例id，然后去查流程实例详情。然后设置员工不限制ip日期
     * </p>
     * 2022/08/01 00:00:00 - 2022/08/11 23:59:59
     *
     * @param message 不限ip流程mq
     */
    void dealIpOpenDate(String message);

    /**
     * 描述: 查询
     *
     * @param staffId
     * @return java.util.List<com.zmn.mcc.model.entity.staff.McStaff>
     * @author jiafei
     * @since 2022/7/28 15:57
     */
    EngineerBasicInfoDRO getEngineerByStaffId(Integer staffId);

    /**
     * 描述: 绑定工程师
     *
     * @param staffId    staffId
     * @param engineerId engineerId
     * @param operator   operator
     * @author xyh
     * @since 2022/7/28 15:57
     */
    Boolean bindingStaffAndMaster(@NotNull(message = "参数不能为null") Integer engineerRole, @NotNull(message = "参数不能为null") Integer staffId, @NotNull(message = "参数不能为null") Integer engineerId, @NotNull(message = "操作人不能为null") String operator);
}
